﻿using System;
using System.Collections.Generic;
using System.Text;
using MToolStudio.Render;

namespace MToolStudio
{
    public class IdGenerator
    {
        private static IdGenerator instance = new IdGenerator();

        public static IdGenerator Instance
        {
            get { return instance; }
        }

        private List<string> actionIds = new List<string>();
        private int actionIdCounter;
        private List<string> stateIds = new List<string>();
        private int stateIdCounter;

        private IdGenerator()
        { }

        public void Reset()
        {
            actionIds.Clear();
            stateIds.Clear();
            actionIdCounter = 0;
            stateIdCounter = 0;
        }

        public bool IsStateIdValid(string id)
        {
            return !stateIds.Contains(id);
        }

        public bool IsActionIdValid(string id)
        {
            return !actionIds.Contains(id);
        }

        public string NextStateId()
        {
            while (!IsStateIdValid("state_" + stateIdCounter))
                stateIdCounter++;
            UseState("state_" + stateIdCounter);
            return "state_" + stateIdCounter;
        }

        public string NextActionId()
        {
            while (!IsActionIdValid("action_" + actionIdCounter))
                actionIdCounter++;
            UseAction("action_" + actionIdCounter);
            return "action_" + actionIdCounter;
        }

        public string NextStateId(string id)
        {
            string retv = id;
            if (!IsStateIdValid(id))
            {
                int modifyCounter = 1;
                while (!IsStateIdValid(string.Format("{0}({1})", id, modifyCounter)))
                    modifyCounter++;
                retv = string.Format("{0}({1})", id, modifyCounter);
            }
            UseState(retv);
            return retv;
        }

        public string NextActionId(string id)
        {
            string retv = id;

            if (!IsStateIdValid(id))
            {
                int modifyCounter = 1;
                while (!IsActionIdValid(string.Format("{0}({1})", id, modifyCounter)))
                    modifyCounter++;
                retv = string.Format("{0}({1})", id, modifyCounter);
            }
            UseAction(retv);
            return retv;
        }

        public void RemoveActionId(string id)
        {
            actionIds.Remove(id);
        }

        public void RemoveStateId(string id)
        {
            stateIds.Remove(id);
        }

        protected void UseState(string id)
        {
            if (stateIds.Contains(id))
                throw new Exception(string.Format("State id duplicate found in UseState({0})", id));
            stateIds.Add(id);
        }

        protected void UseAction(string id)
        {
            if (actionIds.Contains(id))
                throw new Exception(string.Format("Action id duplicate found in UseAction({0})", id));
            actionIds.Add(id);
        }

        public bool TryStateNewId(string oldId, string newId)
        {
            if (stateIds.Contains(newId))
                return false;
            UseState(newId);
            RemoveStateId(oldId);
            return true;
        }

        public bool TryActionNewId(string oldId, string newId)
        {
            if (actionIds.Contains(newId))
                return false;
            UseAction(newId);
            RemoveActionId(oldId);
            return true;
        }
    
        public void LoadFromStudioData(MToolStudioData data)
        {
 	        Reset();
            foreach(ActionR ac in data.Actions)
            {
                UseAction(ac.InnerAction.Id);
            }
            foreach (StateR st in data.States)
            {
                UseState(st.InnerState.Id);
            }
        }
    }
}
